import React, {
  useEffect,
  useState,
  useRef,
  useCallback,
  useMemo,
} from 'react';
import './index.css';
import * as XLSX from 'xlsx';
import { useNavigate } from 'react-router-dom';
import { Button, Select } from 'antd';
import { LeftCircleFilled, DeleteFilled } from '@ant-design/icons';
import CodeMirror from '@uiw/react-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import t1 from './t1';
import t2 from './t2';

function DiyPage() {
  const [filePath, setPath] = useState('');

  const bookRef = useRef<any>(null);

  const navigater = useNavigate();

  const decodeFnc = useMemo(
    () => [
      { name: '解析公式1', id: 't1', fnc: t1 },
      { name: '解析公式2', id: 't2', fnc: t2 },
    ],
    [],
  );

  const [selectedFnc, setSelectedFnc] = useState<string | undefined>();

  const decodeJSON = useMemo(() => {
    if (!bookRef.current) return undefined;
    const outResult: Record<string, any[][]> = {};

    const wb = bookRef.current.Workbook;

    wb.Sheets.forEach((sheet: any) => {
      if (sheet.Hidden !== 1) {
        const { name } = sheet;
        const sheetData = bookRef.current.Sheets[name];

        const json: Array<Array<string>> = XLSX.utils.sheet_to_json(sheetData, {
          raw: true,
          header: 1,
        });

        if (json.length > 0) {
          outResult[name] = json;
        }
      }
    });
    return outResult;
  }, [bookRef]);

  const decodeFile = useCallback(() => {
    if (!decodeJSON || !selectedFnc) return;
    const newJson: Record<string, any[][]> = {};
    const target = decodeFnc.find((item) => item.id === selectedFnc);
    Object.entries(decodeJSON).forEach(([key, value]) => {
      newJson[key] = target!.fnc(value) as any;
    });
    window.electron.ipcRenderer.sendMessage('decodeByJavascript', {
      data: newJson,
    });
  }, [decodeJSON, selectedFnc, decodeFnc]);

  const clearn = () => {
    setPath('');
  };

  useEffect(() => {
    window.electron.ipcRenderer.on('openFile', (result) => {
      const { book, filePath: path } = result as {
        filePath: string;
        book: any;
      };
      bookRef.current = book;
      setPath(path);
    });
  }, []);

  const options = {
    mode: 'text/javascript',
    theme: 'material',
    lineNumbers: true,
    lineWrapping: true,
    foldGutter: true,
    gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
    matchBrackets: true,
    autoCloseTags: true,
    highlightSelectionMatches: true,
  };

  return (
    <div className="diy-page">
      <div className="header">
        <Button
          type="default"
          ghost
          size="large"
          title="返回"
          onClick={() => {
            navigater('/');
          }}
          icon={<LeftCircleFilled />}
        >
          返回
        </Button>
      </div>

      {!filePath && (
        <div className="container">
          <button
            className="button"
            type="button"
            onClick={() => {
              window.electron.ipcRenderer.sendMessage('openFile');
            }}
          >
            打开
          </button>
        </div>
      )}

      {filePath && (
        <div className="decode-pane">
          <h3>
            {filePath}
            <Button type="text" icon={<DeleteFilled />} onClick={clearn} />
          </h3>

          <div className="group">
            <h3>解析源数据JSON:</h3>
            <div className="value-box">
              <CodeMirror
                value={JSON.stringify(decodeJSON || '')}
                theme="dark"
                height="100px"
                extensions={[javascript({ jsx: true })]}
                basicSetup={options}
              />
            </div>
          </div>

          <div className="group">
            选择公式：
            <Select
              placeholder="选择公式"
              value={selectedFnc}
              onChange={setSelectedFnc}
            >
              {decodeFnc.map((item) => {
                return (
                  <Select.Option key={item.name} value={item.id}>
                    {item.name}
                  </Select.Option>
                );
              })}
            </Select>
          </div>

          <button
            disabled={!selectedFnc}
            className="button"
            type="button"
            onClick={decodeFile}
          >
            执行
          </button>
        </div>
      )}
    </div>
  );
}

export default DiyPage;
